#ifndef __TORNEO__H__
#define __TORNEO__H__

#include "Includes.h"
#include "Reloj.h"
#include "AdministradorMemoriaCompartida.h"
#include "AdministradorClientes.h"
#include "AdministradorPartidas.h"
#include "AdministradorEstadisticas.h"
#include "TerminadorPartidas.h"
#include "IngresoTeclado.h"

class AdministradorClientes;
class AdministradorEstadisticas;
class AdministradorPartidas;
class TerminadorPartidas;
class Reloj;
class IngresoTeclado;
class Torneo {

private:
	int cnPartidas;
	Reloj* reloj;
	bool mostrarPartidas;
	AdministradorClientes* administradorClientes;
	AdministradorPartidas* administradorPartidas;
	IngresoTeclado *ingresoTeclado;
	TerminadorPartidas* terminadorPartidas;
	AdministradorEstadisticas* administradorEstadisticas;
	AdministradorMemoriaCompartida* administradorMemoriaCompartida;
	Semaforo* contadorJugadoresDisponibles;
	ThreadMutex* mutexJugadoresDisponibles;
	ThreadMutex* mutexPartidas;
	ThreadMutex* mutexRanking;
	ThreadMutex* mutexTorneoFinalizado;
	Socket* socket;
	Log* torneoLogger;
	map<const string, string> mapaConfiguracion;
	list<t_jugador> jugadoresDisponibles;
	list<t_partida> partidas;
	list<t_estadistica_jugador> ranking;
	time_t tiempoActual;
	time_t tiempoInicial;
	time_t tiempoFinal;
	bool finalizado;
	bool iniciado;
	int tiempoTorneo;
	int getValorPropiedadConfiguracion(const char* port);
	void iniciarThreads();
	void juntarThreads();
	void inicializarSocket();
	void matarPartidas();
	void esperarPartidas(bool hayError);

public:
	Torneo();
	void notificarFinTorneo(bool hayError, int socketJ);
	void notificarFinPartida(int socketJ);
	void parsearArchivoConfiguracion();
	void ejecutar();
	void inicializarThreads();
	void enlistarJugadorDisponible(t_jugador* jugador);
	void enlistarJugadorRanking(t_jugador* jugador);
	void desenlistarJugadorDisponible(std::list<t_jugador>::iterator it);
	void calcularTiempoTorneo();
	void terminarTorneo(bool hayError);
	void finalizarJugadoresDisponibles(bool hayError);
	void abortarTorneo();
	//Getter & Setters
	AdministradorMemoriaCompartida* getAdministradorMemoriaCompartida();
	void setAdministradorMemoriaCompartida(AdministradorMemoriaCompartida* administradorMemoriaCompartida);
	list<t_jugador>& getJugadoresDisponibles();
	void setJugadoresDisponibles(list<t_jugador>& jugadoresDisponibles);
	list<t_partida>& getPartidas();
	void setPartidas(list<t_partida>& partidas);
	int getTiempoTorneo();
	void setTiempoTorneo(int tiempoTorneo);
	Socket* getSocket();
	void setSocket(Socket* socket);
	Semaforo* getContadorJugadoresDisponibles();
	void setContadorJugadoresDisponibles(Semaforo* contadorJugadoresDisponibles);
	ThreadMutex* getMutexJugadoresDisponibles();
	void setMutexJugadoresDisponibles(ThreadMutex* mutexJugadoresDisponibles);
	ThreadMutex* getMutexPartidas();
	void setMutexPartidas(ThreadMutex* mutexPartidas);
	list<t_estadistica_jugador> *getRanking();
	void setRanking(list<t_estadistica_jugador> *ranking);
	Log* getTorneoLogger();
	void setTorneoLogger(Log* torneoLogger);
	time_t getTiempoFinal();
	void setTiempoFinal(time_t tiempoFinal);
	time_t getTiempoInicial();
	void setTiempoInicial(time_t tiempoInicial);
	bool isFinalizado();
	void setFinalizado(bool finalizado);
	time_t* getTiempoActual();
	void setTiempoActual(time_t tiempoActual);
	Reloj* getReloj();
	void setReloj(Reloj* reloj);
	AdministradorEstadisticas* getAdministradorEstadisticas();
	void setAdministradorEstadisticas(AdministradorEstadisticas* administradorEstadisticas);
	ThreadMutex* getMutexRanking();
	void setMutexRanking(ThreadMutex* mutexRanking);
	bool isIniciado();
	void setIniciado(bool iniciado);
	ThreadMutex* getMutexTorneoFinalizado();
	IngresoTeclado *getIngresoTeclado();
	void setMostrarPartidas(bool mostrarPartidas);
	bool isMostrarPartidas();
	void setMutexTorneoFinalizado(ThreadMutex* mutexTorneoFinalizado);
	int getCnPartidas();
	void addPartidas();
	void decPartidas();
};
#endif
